import {
	mapActions,
	mapGetters
} from 'vuex';
import {
	cloudContextInit,
	connectRongCloud,
	getAllConversation,
	getOppositeIdFrom,
	imService,
	RongIMLib,
} from '../rongCloud/cloudUtil';
import {
	MSG_TYPE,
	rongEvent
} from '../rongCloud/messaging';
import {
	didntLoggedIn,
	rongGetChatterProfile,
	uniGetStorageSync,
} from '../funcs';

import {
	CURRENT_USER_KEY
} from '../misc';
import {
	CHAT_IGNORE_BADGE_COUNT
} from '../test';
import {
	USER_ORIENTED
} from '../config';
import {
	filter
} from './filter';

export const chatMixin = {
	mixins: [filter],

	data() {
		return {
			msgStatus: 'nomore', // 与下面一一对应
			msgContentText: {
				contentdown: '上拉加载更多', // more
				contentrefresh: '聊天记录加载中', // loading
				contentnomore: '没有更多', // nomore
			},
			currentUser: uniGetStorageSync(CURRENT_USER_KEY),
			chatContextInited: false,
			connectAgain: false,
		};
	},

	computed: {
		...mapGetters('chat', [
			'sConversationList',
			'sChatHistoryList',
			'sEmojiActive',
			'canSendHouseCard',
			'sHouseItem',
		]),
	},

	mounted() {},

	methods: {
		...mapActions('chat', [
			'set_sConversationList',
			'set_sChatHistoryList',
			'set_sEmojiActive',
			'set_canSendHouseCard',
			'set_sHouseItem',
		]),

		async chatContextInitialize() {
			// 全局聊天初始化, 用于登录之后立刻初始化聊天环境
			if (this.chatContextInited) return;
			if (didntLoggedIn(false)) return;
			let res = await this.initRongCloud();
			console.log('聊天初始化结果: ', res);
			if (!res || !res.id) {
				// 说明没有初始化成功或者没有登录
				// uniShowToast('请登陆后使用聊天功能', false)
				console.warn('初始化失败 res :', res);
				return;
			}

			let status = true;
			let user_rcid = uniGetStorageSync(CURRENT_USER_KEY).rongcloud_id;
			// 注册事件: 有新消息就更新全局会话列表
			uni.$on(rongEvent.chattingMessageSuccess, (message) => {
				// 消息类型为RC:SRSMsg,清除未读数
				console.log("推送的消息",message)
				if (message.senderUserId != user_rcid) {
					if (message.messageType != "RC:SRSMsg") {
						status = false;
						setTimeout(() => {
							// 进行一次全局会话更新，太快的话全局更新会话不是最新的
							console.log("推送未读",message)
							this.updateGlobalConversation();
							this.pushSystemNotification(message);
						}, 300);
					}
				} else {
					if (message.messageType == "RC:SRSMsg") {
						// console.log("触发多端清除未读数");
						console.log("推送已读",message)
						let conversation = imService.Conversation.get({
							targetId: message.targetId,
							type: RongIMLib.CONVERSATION_TYPE.PRIVATE
						});
						conversation.read();
						this.updateTabBarBadge();
					}
				}
			});
			if (status) this.updateGlobalConversation();
			this.chatContextInited = true;
		},
		
		async initRongCloud() {
			await cloudContextInit();
			return connectRongCloud();
		},

		// 更新全局会话,
		async updateGlobalConversation(toReset) {
			if (toReset) {
				// 重置全局会话
				this.set_sConversationList([]);
			} else {
				this.msgStatus = 'loading';
				getAllConversation()
					.then((resList) => {
						console.log('resList', resList);
						// debugger
						this.set_sConversationList(resList);
						uni.$emit(rongEvent.globalConversationUpdated);
						this.updateTabBarBadge();
					})
					.catch((res) => {
						console.log('error getting conversation ', res);
					})
					.finally((res) => {
						this.msgStatus = 'nomore';
					});
			}
		},

		async deleteConversation(targetId) {
			// console.log(im)
			await this.markConversationAsRead(targetId);
			var conversation = imService.Conversation.get({
				targetId: targetId,
				type: RongIMLib.CONVERSATION_TYPE.PRIVATE,
			});
			return conversation.destory();
		},

		// 删除指定聊天id的会话列表
		async deleteConversationById(targetId, toUpdateGlobalConversation = false) {
			return new Promise(async (resolve) => {
				await this.markConversationAsRead(targetId);
				this.deleteConversation(targetId).then(async (res) => {
					if (toUpdateGlobalConversation) {
						let newList = await getAllConversation();
						// console.log('newList: ' , newList);
						this.set_sConversationList(newList);

						// console.log('updated', this.sConversationList);
					}
					// console.log('delete conversation res: ', targetId, res);
					resolve(res);
				});
			});
		},
		/**
		 *
		 * @returns {Promise<[]>}
		 */
		async deleteAllConversation() {
			return new Promise(async (resolve) => {
				// console.log(this.sConversationList);
				for (let conversation of this.sConversationList) {
					let targetId = getOppositeIdFrom(conversation);
					let deleteRes = await this.deleteConversationById(targetId);
					console.log('deleteRes: ', targetId, '\n', deleteRes);
				}
				this.set_sConversationList([]);
				this.updateTabBarBadge();

				resolve();
			});
		},

		// 更新tabBar未读红点显示
		updateTabBarBadge() {
			// console.log('sConversationList: ', this.sConversationList)
			let total = 0;
			for (let conversation of this.sConversationList) {
				total += conversation.unreadMessageCount;
			}
			if (total > 99) {
				total = '...';
			}
			if (total > 0 && !CHAT_IGNORE_BADGE_COUNT) {
				uni.setTabBarBadge({
					index: 2,
					text: total.toString(),
				});
			} else {
				// console.log('清空 badge');
				uni.removeTabBarBadge({
					index: 2,
				});
			}
		},

		// 清除单个会话未读数
		markConversationAsRead(targetId) {
			return new Promise((resolve) => {
				var conversation = imService.Conversation.get({
					targetId: targetId,
					type: RongIMLib.CONVERSATION_TYPE.PRIVATE,
				});
				conversation.read().then(() => {
					let cList = this.sConversationList;
					// 多端同步未读数
					for (let i = 0; i < cList.length; i++) {
						if (cList[i].targetId == targetId) {
							conversation.send({
								messageType: 'RC:SRSMsg',
								content: {
									//从消息里获取服务器端时间，以最近一条已读 message 为准
									lastMessageSendTime: cList[i].latestMessage.sentTime
								}
							})
							// console.log("发送多端同步未读数通知");
							break
						}
					}
					this.updateTabBarBadge();
					resolve();
				});
			});
		},

		// 推送通知到系统
		async pushSystemNotification(message) {
			// console.log('new message~~~');
			let str = '您有一条新消息';
			if (message.messageType === MSG_TYPE().TEXT) {
				str = message.content.content;
			} else {
				str = this.displayChatContent(message);
			}
			let oProfile = await rongGetChatterProfile(message.senderUserId);
			let title = USER_ORIENTED ? '招商人员' : '客户';
			title = oProfile.name && oProfile.name;
			// #ifdef APP-PLUS
			plus.push.createMessage(str, '启租招商', {
				title: title,
				cover: true,
			});
			// #endif
		},
		
		// 断开融云链接
		imDisconnect() {
			imService.disconnect().then(() => console.log('断开链接成功'));
		},
	},

};

/**
 * 对Date的扩展，将 Date 转化为指定格式的String。
 *
 *  月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
 *  年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)。
 *
 *  【示例】：
 *  common.formatDate(new Date(), 'yy-MM-dd hh:mm:ss.S') ==> 2006-07-02 08:09:04.423
 *  common.formatDate(new Date(), 'yy-M-d h:m:s.S')      ==> 2006-7-2 8:9:4.18
 *  common.formatDate(new Date(), 'hh:mm:ss.S')            ==> 08:09:04.423
 *
 *  @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
 */
var _formatDate = function(date, fmt) {
	var o = {
		'M+': date.getMonth() + 1, //月份
		'd+': date.getDate(), //日
		'h+': date.getHours(), //小时
		'm+': date.getMinutes(), //分
		's+': date.getSeconds(), //秒
		'q+': Math.floor((date.getMonth() + 3) / 3), //季度
		S: date.getMilliseconds(), //毫秒
	};
	if (/(y+)/.test(fmt))
		fmt = fmt.replace(
			RegExp.$1,
			(date.getFullYear() + '').substr(4 - RegExp.$1.length)
		);
	for (var k in o)
		if (new RegExp('(' + k + ')').test(fmt))
			fmt = fmt.replace(
				RegExp.$1,
				RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
			);
	return fmt;
};

/**
 * 仿照微信中的消息时间显示逻辑，将时间戳（单位：毫秒）转换为友好的显示格式.
 *
 * 1）7天之内的日期显示逻辑是：今天、昨天(-1d)、前天(-2d)、星期？（只显示总计7天之内的星期数，即<=-4d）；
 * 2）7天之外（即>7天）的逻辑：直接显示完整日期时间。
 *
 * @param timestamp   时间戳（单位：毫秒），形如：1550789954260
 * @param {boolean} mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”
 * ，否则不包含（参考微信，不包含时分的情况，用于首页“消息”中显示时）
 *
 * @return {string} 输出格式形如：“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
 * @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
 * @since 1.1
 */
export var _getTimeStringAutoShort2 = function(timestamp, mustIncludeTime) {
	// 当前时间
	var currentDate = new Date();
	// 目标判断时间
	var srcDate = new Date(parseInt(timestamp));

	var currentYear = currentDate.getFullYear();
	var currentMonth = currentDate.getMonth() + 1;
	var currentDateD = currentDate.getDate();

	var srcYear = srcDate.getFullYear();
	var srcMonth = srcDate.getMonth() + 1;
	var srcDateD = srcDate.getDate();

	var ret = '';

	// 要额外显示的时间分钟
	var timeExtraStr = mustIncludeTime ? ' ' + _formatDate(srcDate, 'hh:mm') : '';

	// 当年
	if (currentYear == srcYear) {
		var currentTimestamp = currentDate.getTime();
		// 相差时间（单位：毫秒）
		var deltaTime = currentTimestamp - timestamp;

		// 当天（月份和日期一致才是）
		if (currentMonth == srcMonth && currentDateD == srcDateD) {
			// 时间相差60秒以内
			if (deltaTime < 60 * 1000) ret = '刚刚';
			// 否则当天其它时间段的，直接显示“时:分”的形式
			else ret = _formatDate(srcDate, 'hh:mm');
		}
		// 当年 && 当天之外的时间（即昨天及以前的时间）
		else {
			// 昨天（以“现在”的时候为基准-1天）
			var yesterdayDate = new Date();
			yesterdayDate.setDate(yesterdayDate.getDate() - 1);

			// 前天（以“现在”的时候为基准-2天）
			var beforeYesterdayDate = new Date();
			beforeYesterdayDate.setDate(beforeYesterdayDate.getDate() - 2);

			// 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较，是最为准确的（如果用时间戳差值
			// 的形式，是不准确的，比如：现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00，
			// 这两者间只相差2小时，直接用“deltaTime/(3600 * 1000)” > 24小时来判断是否昨天，就完全是扯蛋的逻辑了）
			if (
				srcMonth == yesterdayDate.getMonth() + 1 &&
				srcDateD == yesterdayDate.getDate()
			)
				ret = '昨天' + timeExtraStr;
			// -1d
			// “前天”判断逻辑同上
			else if (
				srcMonth == beforeYesterdayDate.getMonth() + 1 &&
				srcDateD == beforeYesterdayDate.getDate()
			)
				ret = '前天' + timeExtraStr;
			// -2d
			else {
				// 跟当前时间相差的小时数
				var deltaHour = deltaTime / (3600 * 1000);

				// 如果小于或等 7*24小时就显示星期几
				if (deltaHour <= 7 * 24) {
					var weekday = new Array(7);
					weekday[0] = '星期日';
					weekday[1] = '星期一';
					weekday[2] = '星期二';
					weekday[3] = '星期三';
					weekday[4] = '星期四';
					weekday[5] = '星期五';
					weekday[6] = '星期六';

					// 取出当前是星期几
					var weedayDesc = weekday[srcDate.getDay()];
					ret = weedayDesc + timeExtraStr;
				}
				// 否则直接显示完整日期时间
				else ret = _formatDate(srcDate, 'yy/M/d') + timeExtraStr;
			}
		}
	}
	// 往年
	else {
		ret = _formatDate(srcDate, 'yy/M/d') + timeExtraStr;
	}

	return ret;
};
